package src; 

import javax.swing.UIManager;

import java.awt.event.*;

import javax.swing.*; 

import java.awt.*;


/**
 * The Controller class is the link between the game logic and the GUI (the graphical representation 
 * of the game). The Controller is also the overarching class that sets up the game, listens to clicks
 * and sends them to the game to be processed. 
 * @author Akshat
 *
 */
public class SuperTicTacToeController implements MouseListener, ActionListener
{
	private SuperTicTacToeGame game;
	private GUI_Login login; 
	private GUI_Board board; 
	private JFrame frame; 
		
	public SuperTicTacToeController()
	{		
		login = new GUI_Login(this);
		
		while(login.getSelectedIndex() == 0 && login.getPlayers() == null )
		{
			JOptionPane.showConfirmDialog(null, login,"SUPERTicTacToe - LOGIN", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
		}

		frame = new JFrame(); 
		frame.setSize(600, 600);
		frame.setLocation(100,100);
		
		if( login.getSelectedIndex() == 0 )
		{
			frame.setTitle("SUPERTicTacToe - " + login.getPlayers()[0] + " vs " + login.getPlayers()[1] + "!!");
			game = new SuperTicTacToeGame(this);
			game.setPlayers(login.getPlayers());
		}
		else
		{
			frame.setTitle("SUPERTicTacToe - Online!!");
			game = new NetworkedSuperTicTacToeGame(this); 
		}
			
		// Window Listeners
		frame.addWindowListener(new WindowAdapter()
			{
			  	public void windowClosing(WindowEvent e) 
			  	{
				   System.exit(0);
			  	} //windowClosing
			} 
		);
	
		boolean play = true; 
		
		while( play )
		{
			board = new GUI_Board(game.getBoard(), this); 
			
			frame.add(board);
			frame.setVisible(true);
			frame.pack();
			
			game.playGame();
			
			int again; 
			
			if( game.getWon() )
			{
				again = JOptionPane.showConfirmDialog(null, game.getCurrentPlayer() + " wins! Play Again?");
			}
			else
			{
				again = JOptionPane.showConfirmDialog(null, "It's a Tie!! Play Again?");
			}
			
			if( again == 0)
			{
				play = true; 
				game.reset();
				frame.remove(board);
			}
			else
			{
				play = false; 
			}
			
		}
		
		JOptionPane.showMessageDialog(null, "Thanks for playing!");
	}
	
	public SuperTicTacToeController(boolean networked)
    {       
        login = new GUI_Login(this);
        
        while(login.getSelectedIndex() == 0 && login.getPlayers() == null )
        {
            JOptionPane.showConfirmDialog(null, login,"SUPERTicTacToe - LOGIN", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
        }

        frame = new JFrame(); 
        frame.setSize(600, 600);
        frame.setLocation(100,100);
        
        if( !networked)
        {
            frame.setTitle("SUPERTicTacToe - " + login.getPlayers()[0] + " vs " + login.getPlayers()[1] + "!!");
            game.setPlayers(login.getPlayers());
        }
        else
        {
            frame.setTitle("SUPERTicTacToe - Online!!");
            game = new NetworkedSuperTicTacToeGame(this); 
        }
            
        // Window Listeners
        frame.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e) 
            {
               System.exit(0);
            } //windowClosing
        } 
        );
        
        board = new GUI_Board(game.getBoard(), this); 
        
        frame.add(board);
        frame.pack();
        frame.setVisible(true);
        
        game.playGame();
    }

	/**
	 * Getter method for game private variable
	 * @return reference to SuperTicTacToeGame game variable
	 */
	public SuperTicTacToeGame getGame()
	{
		return game; 
	}
	
	/**
	 * Getter method for board private variable
	 * @return reference to GUI_Board board variable
	 */
	public GUI_Board getBoard()
	{
		return board; 
	}
	
	/**
	 * For use by the GUI classes to indicate which board is currently playable
	 * @return the current playable SubGrid
	 */
	public SubGrid getCurrentSubGrid()
	{
		return game.getCurrentSubGrid(); 
	}
	
	/**
	 * Repaints all the grids on the board. Implemented in controller so that it can be 
	 * called from within the game logic (controller passed as constructor argument to most
	 * high level logic elements). 
	 */
	public void repaintGUI()
	{
		board.paintAllGrids(); 
	}

	@Override
	/**
	 *The Controller class serves as a medium of communication between the logic and the GUI. All events on the GUI (such as clicking)
	 *are communicated back to the Game (the logic) to be interpreted.
	 *@param e MouseEvent that was triggered
	 */
	public void mouseClicked(MouseEvent e) 
	{		
		GUI_SubGrid source = (GUI_SubGrid)(e.getSource()); 
		
		int x = e.getX(); 
		int y = e.getY(); 
		
		x -= source.getLineWidth() * (x/source.getCellWidth()); 
		y -= source.getLineWidth() * (y/source.getCellHeight());
		
		int col = x/source.getCellWidth();
		int row = y/source.getCellHeight();
		
		if (game.getCurrentPlayer() instanceof NetworkPlayer && !((NetworkPlayer)(game.getCurrentPlayer())).getLocal())
		{
		    
		}
		else
		{
		    GridLocation loc = new GridLocation(source.getGrid().getMainRow(), source.getGrid().getMainCol(), row, col);
	        game.moveMade(loc); 
		}
		
		source.draw(source.getGraphics());
	}


	@Override
	public void mouseEntered(MouseEvent e) 
	{
		
	}


	@Override
	public void mouseExited(MouseEvent e) 
	{
		
	}


	@Override
	public void mousePressed(MouseEvent e) 
	{
		
	}


	@Override
	public void mouseReleased(MouseEvent e) 
	{
		
	}

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		
	}

}
